package com.uduemc.security.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.annotation.JsonView;
import com.uduemc.security.dto.QueryCustomer;
import com.uduemc.security.exception.NotFoundException;
import com.uduemc.security.extities.Customer;

@RestController
public class CustomerController {

	/**
	 * 
	 * @param queryCustomer
	 * @param pageable
	 *            Pageable 获取请求中传递过来的三个参数 size: 显示数据的大小 page: 页码 sort: 排序方式
	 *            可以使用 @PageableDefault(page=2, size=10) 配置默认值
	 * @param request
	 * @return
	 */
	@GetMapping("/customer")
	@JsonView(Customer.customerSimpleView.class)
	public List<Customer> index(QueryCustomer queryCustomer, @PageableDefault(page = 2, size = 10) Pageable pageable,
			HttpServletRequest request) {

		String string = ReflectionToStringBuilder.toString(queryCustomer, ToStringStyle.MULTI_LINE_STYLE);
		System.out.println("queryCustomer: " + string);
		// System.out.println(queryCustomer);

		System.out.println("pageable: " + ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));

		System.out.println("request headers: " + Collections.list(request.getHeaderNames()));

		// 输出请求的方式
		System.out.println("Content-Type: " + request.getHeader("Content-Type"));

		List<Customer> result = new ArrayList<>();
		result.add(new Customer());
		result.add(new Customer());
		result.add(new Customer());
		return result;
	}

	/**
	 * 通过@JsonView查询Customer全部信息内容
	 */
	@GetMapping("/customer/{id:\\d+}")
	@JsonView(Customer.customerDetailView.class)
	public Customer get(@PathVariable("id") Integer id) {
		Customer customer = new Customer();
		customer.setId(id).setName("select-name").setAge((short) 18).setSex((short) 1).setAuthKey("select-authkey")
				.setCreateAt(new Date());
		return customer;
	}

	/**
	 * 使用 @RequestBody 获取请求体中的文本内容转化实例对象 使用 @Valid 验证注解，在实体类中使用
	 * org.hibernate.validator 包的验证注解，例如 @NotBlank 使用 BindingResult 获取验证不通过时的错误内容
	 * 
	 * @param customer
	 * @param errors
	 * @return
	 */
	@PostMapping("/create")
	public Customer create(@Valid @RequestBody Customer customer, BindingResult errors) {
		System.out.println("请求体解析后：".concat(customer.toString()));
		if (errors.hasErrors()) {
			errors.getFieldErrors().stream().forEach(item -> {
				System.out.println(item);
			});
		}
		customer.setId(1);
		customer.setAuthKey("abcdefg");
		customer.setCreateAt(new Date());
		return customer;
	}

	@GetMapping("/create")
	public ModelAndView createGet() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("create");
		return mav;
	}

	@PutMapping("/update/{id:\\d+}")
	@JsonView(Customer.customerDetailView.class)
	public Customer update(@Valid @RequestBody Customer customer, BindingResult errors) {
		System.out.println("请求体解析后：".concat(customer.toString()));
		if (errors.hasErrors()) {
			errors.getFieldErrors().stream().forEach(error -> {
				FieldError fError = (FieldError) error;
				System.out.println(fError.getField() + ": " + error.getDefaultMessage());
			});
		}
		customer.setAuthKey("abcdefg");
		customer.setCreateAt(new Date());
		return customer;
	}

	@GetMapping("/exception/{id:\\d+}")
	public Customer exception(@PathVariable("id") Integer id) {
		Customer customer = null;
		if (id == null || id < 1 || (customer = mockCustomers(id)) == null) {
			throw new NotFoundException(id);
		}
		return customer;
	}

	public Customer mockCustomers(Integer id) {
		if (id < 1) {
			return null;
		}
		return new Customer().setId(id);
	}
}
